package br.uece.laconi.tac;

import se.sics.tac.aw.Bid;
import se.sics.tac.aw.Quote;
import se.sics.tac.aw.TACAgent;
import se.sics.tac.aw.Transaction;
import br.uece.laconi.util.Util;

public class AgentSensor {
	Agent agent = null;
	//TACAgent tacAgent;
	
	public AgentSensor(Agent agent) {
		this.agent = agent; 
	}

	/* The auction with id "auction" has closed */
	public void auctionClosed(int auction) {
		agent.effector.log.fine("*** Auction " + auction + " closed!");
	}

	/* The bid contained errors (error represent error status - commandStatus) */
	public void bidError(Bid bid, int error) {
		agent.effector.log.warning("Bid Error in auction " + bid.getAuction() + ": "
				+ error + " (" + agent.getTACAgent().commandStatusToString(error) + ')');
	}

	/* The bid has been rejected (reason is bid.getRejectReason()) */
	public void bidRejected(Bid bid) {
		agent.effector.log.warning("Bid Rejected: " + bid.getID() + " auction "+ bid.getAuction() + " quantity " + bid.getQuantity() + " price " + bid.getPrice(0));
		agent.effector.log.warning("      Reason: " + bid.getRejectReason() + " ("
				+ bid.getRejectReasonAsString() + ')');
	}

	/* There are TACAgent have received an answer on a bid query/submission (new
	 * information about the bid is available)
	 */
	public void bidUpdated(Bid bid) {
		agent.effector.log.fine("Bid Updated: id=" + bid.getID() + " auction="
				+ bid.getAuction() + " state="
				+ bid.getProcessingStateAsString());
		agent.effector.log.fine("       Hash: " + bid.getBidHash());
	}

	/* A TAC game has started, and all information about the game is available
	 * (preferences etc)
	 */
	public void gameStarted() {
		agent.fs.init();
		agent.hs.init();
//		agent.es.init();
		
		//carrega base com os dados iniciais
		reiniciarBase();
		
		//adaptacao a partir do 04:00 de jogo e a cada minuto posterior
		//o que leva a um decrescimo ou acrescimo de ate 40% do valor dos parametros		
//		for (int i = 0; i <= 3; i++) {
//			agent.adapter.init(240000+60000*i);
//
//		}
		
		//calculo da alocacao a partir do 00:00 de jogo e a cada 60 segundos posteriores		
		for (int i = 0; i <= 7; i++) {
			agent.alocador.init(10000 + 60000*i);
		}	
		agent.effector.log.fine("Game " + agent.getTACAgent().getGameID() + " started!");
	}
	
	/** carrega a base de conhecimento com os dados iniciais do jogo **/
	public void reiniciarBase(){
		agent.base.init();
		int [][] a = new int[8][6];
		for (int i=0; i<8; i++) {
			for (int j=0; j<6; j++) {
				a[i][j] = getClientPreference(i, j);
			}
		}
		Util.visualizarMatriz(a, "preferencias");
		agent.base.setPreferencias(a);
		int [][] b = new int[5][7];
		for (int i=0; i<28; i++) {
			int d = TACAgent.getAuctionDay(i);
			b[d-1][i/4] = getOwn(i);//valor max i = 27, logo valor max de i/4 = 6;
		}
		agent.base.setInventario(b);
		Util.visualizarMatriz(b, "own");
	}
	
	/* The current game has ended */
	public void gameStopped() {
		agent.effector.log.fine("Game Stopped!");
	}

	public void quoteUpdated(int auctionCategory) {
		agent.effector.log.fine("All quotes for "
				+ TACAgent.auctionCategoryToString(auctionCategory)
				+ " has been updated");
	}

	public void quoteUpdated(Quote quote) {
	    int auction = quote.getAuction();
		int auctionCategory = TACAgent.getAuctionCategory(auction);
		
		if (auctionCategory == TACAgent.CAT_FLIGHT) {
			// FlightStrategy
		} else if (auctionCategory == TACAgent.CAT_HOTEL) {
			// HotelStrategy
			agent.hs.update(quote);
		} else if (auctionCategory == TACAgent.CAT_ENTERTAINMENT) {
			// EntertainmentStrategy
			/* uma vez a cada atualizacao da cotacao, eh reiniciada a estrutura que guarda os lances enviados */
			int dia = TACAgent.getAuctionDay(auction) - 1;
			int tipo = TACAgent.getAuctionType(auction) - 1;
			agent.base.setAsko(dia, tipo, (int)quote.getAskPrice());
			agent.base.setBido(dia, tipo, (int)quote.getBidPrice());
			
			//atualiza preco estimado pela RN
			agent.base.atualizarEstimativaPrecoRN(auction, quote.getAskPrice(), quote.getBidPrice(), this.getGameTime());
/*			//substituir lances para itens de compra e venda q foram desalocados
			if(agent.base.getDesalocarCompra()[dia][tipo] != 0){
				enviarLance(auction, dia, tipo, quote, "UNALLOCATION_BUY");
			}
			if(agent.base.getDesalocarVenda()[dia][tipo] != 0){
				enviarLance(auction, dia, tipo, quote, "UNALLOCATION_SELL");
			}*/
			//enviar lances alocados para o negociador fuzzy
			if(agent.base.getCompra()[dia][tipo] != 0){
				((Negociador)agent.negociador.get(auction - 16)).strategy.update(quote);
				((Negociador)agent.negociador.get(auction - 16)).strategy.execute("BUY", auction, agent.base.getCompra()[dia][tipo]);
			}if(agent.base.getVende()[dia][tipo] != 0){
				((Negociador)agent.negociador.get(auction - 16)).strategy.update(quote);
				((Negociador)agent.negociador.get(auction - 16)).strategy.execute("SELL", auction, agent.base.getVende()[dia][tipo]);
			}

		}
	}

	public void enviarLance(int auction, int dia, int tipoLeilao, Quote quote, String tipoLance){

	}
	public void transaction(Transaction transaction) {
		int auction = transaction.getAuction();
		int auctionCategory = TACAgent.getAuctionCategory(auction);
		if(auction > 16){
			System.out.println("TRANSCAO DO AGENTE EFETUADA LEILAO " + TACAgent.getAuctionTypeAsString(auction));
			if (auctionCategory == TACAgent.CAT_ENTERTAINMENT) {
				((Negociador)agent.negociador.get(auction - 16)).strategy.update(transaction);
	//			agent.base.se
			}
		}
	}

	public int getClientPreference(int client, int type) {
		return agent.getTACAgent().getClientPreference(client, type);
	}

	public int getAllocation(int auction) {
		return agent.getTACAgent().getAllocation(auction);
	}

	public int getOwn(int auctionID) {
		return agent.getTACAgent().getOwn(auctionID);
	}

	public Bid getBid(int auctionID) {
		return agent.getTACAgent().getBid(auctionID);
	}

	public Quote getQuote(int auctionID) {
		return agent.getTACAgent().getQuote(auctionID);
	}

	public long getGameTime() {
		return agent.getTACAgent().getGameTime();
	}

	public String getGameTimeAsString() {
		return agent.getTACAgent().getGameTimeAsString();
	}

	public String getConfig(String name, String defaultValue) {
		return agent.getTACAgent().getConfig(name, defaultValue);
	}

}
